#include "console_poller.hpp"
#include <boost/thread/locks.hpp>
#include <cstdio>

#ifdef _WIN32
#endif // _WIN32

using namespace std;

namespace mw
{

static const char * DEFAULT_WELCOMME = "Mad World command line interface";
static const char * DEFAULT_PROMPT = "CMD %";

ConsolePoller::ConsolePoller(boost::asio::io_service & io_service)
	:io_service_(io_service), quit_(false)
{
	welcome_ = DEFAULT_WELCOMME;
	prompt_ = DEFAULT_PROMPT;
}

ConsolePoller::~ConsolePoller()
{
	quit_ = true;
	//thread_.join();
}

void ConsolePoller::set_welcome(const string & welcome)
{
	welcome_ = welcome;
}

void ConsolePoller::set_prompt(const string & prompt)
{
	prompt_ = prompt;
}

void ConsolePoller::print_welcome() const
{
	cout << welcome_ << "\n" << endl;
}

void ConsolePoller::start_parse()
{
	// start a thread and hold it with thread_
	boost::thread(boost::bind(&ConsolePoller::run, this)).swap(thread_);
}

void ConsolePoller::stop_parse()
{
	quit_ = true;
#ifdef _WIN32
	DWORD dwTmp;
	INPUT_RECORD ir[2];
	ir[0].EventType = KEY_EVENT;
	ir[0].Event.KeyEvent.bKeyDown = TRUE;
	ir[0].Event.KeyEvent.dwControlKeyState = 288;
	ir[0].Event.KeyEvent.uChar.AsciiChar = 13;
	ir[0].Event.KeyEvent.wRepeatCount = 1;
	ir[0].Event.KeyEvent.wVirtualKeyCode = 13;
	ir[0].Event.KeyEvent.wVirtualScanCode = 28;
	ir[1].EventType = KEY_EVENT;
	ir[1].Event.KeyEvent.bKeyDown = FALSE;
	ir[1].Event.KeyEvent.dwControlKeyState = 288;
	ir[1].Event.KeyEvent.uChar.AsciiChar = 13;
	ir[1].Event.KeyEvent.wRepeatCount = 1;
	ir[1].Event.KeyEvent.wVirtualKeyCode = 13;
	ir[1].Event.KeyEvent.wVirtualScanCode = 28;
	WriteConsoleInput( GetStdHandle( STD_INPUT_HANDLE ), ir, 2, & dwTmp );
#endif
	if (boost::this_thread::get_id() != thread_.get_id())
	{
		printf( "waiting for console thread to quit\n" );
		thread_.join();
	}
	printf( "ConsolePoller quit\n" );

}

void ConsolePoller::print_prompt() const
{
	printf("%s ", prompt_.c_str());
}

void ConsolePoller::run()
{
#ifndef WIN32
	fd_set fds;
	struct timeval tv;
#endif

	print_prompt();
	while ( !quit_ )
	{
#ifdef WIN32
		memset( buffer_, 0, sizeof( buffer_ ) ); 
		if( (fgets( buffer_, MAX_COMMAND_LENGTH, stdin ) == NULL) || quit_ )
			continue;
#else // posix
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		FD_ZERO( &fds );
		FD_SET( STDIN_FILENO, &fds );
		if( select( 1, &fds, NULL, NULL, &tv ) <= 0 )
		{
			continue;
		}

		memset( buffer_, 0, sizeof( buffer_ ) ); 
		if( fgets( buffer_, MAX_COMMAND_LENGTH, stdin ) == NULL )
			continue;
#endif
		process_line(buffer_);
		print_prompt();
	}
}
	
} // end namespace mw
